<?php

namespace app;

use think\Config;

class LdapBase {

    private $connect = '';
    private $base_cn = '';
    private $group_ou = '';
    private $person_ou = '';
    private $old_person_ou = '';
    private $justthese = array("cn", "sn", "displayname", "uid", "employeetype", "telephonenumber", "mobile", "mail", "userpassword");

    /**
     * 初始化ldap链接
     * LdapBase constructor.
     */
    public function __construct() {
        $ldapConf = Config::get("ldap");
        $this->group_ou = $ldapConf['groupOu'];
        $this->person_ou = $ldapConf['personOu'];
        $this->old_person_ou = $ldapConf['oldPersonOu'];
        $host = $ldapConf['host'];
        $port = $ldapConf['port'];
        $adminAccount = $ldapConf['adminAccount'];
        $this->adminPassword = $ldapConf['adminPassword'];
        $this->base_cn = $ldapConf['baseDn'];
        $this->connect = ldap_connect($host, $port) or die("服务器忙，请稍候再试！");

        ldap_set_option($this->connect, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($this->connect, LDAP_OPT_REFERRALS, 0);

        return ldap_bind($this->connect, $adminAccount, $this->adminPassword);
    }

    /**
     * 查询用户
     * @param $findstr
     * @return array
     */
    public function find($findstr) {
        $findArr = explode(',', $findstr);
        $findstr = str_replace('uid=', '', $findArr[0]);
        $filter = "(|(sn=$findstr)(cn=$findstr)(uid=$findstr))";
        $result = ldap_search($this->connect, $this->base_cn, $filter) or die("服务器忙，请稍候再试！");
        $info = ldap_get_entries($this->connect, $result);
        $userInfo['cn'] = isset($info[0]["cn"][0]) ? $info[0]["cn"][0] : '';
        $userInfo['sn'] = isset($info[0]["sn"][0]) ? $info[0]["sn"][0] : '';
        $userInfo['displayname'] = isset($info[0]["displayname"][0]) ? $info[0]["displayname"][0] : '';
        $userInfo['uid'] = isset($info[0]["uid"][0]) ? $info[0]["uid"][0] : '';
        $userInfo['mail'] = isset($info[0]["mail"][0]) ? $info[0]["mail"][0] : '';
        $userInfo['mobile'] = isset($info[0]["mobile"][0]) ? $info[0]["mobile"][0] : '';
        $userInfo['telephonenumber'] = isset($info[0]["telephonenumber"][0]) ? $info[0]["telephonenumber"][0] : '';
        $userInfo['employeetype'] = isset($info[0]["employeetype"][0]) ? $info[0]["employeetype"][0] : '';
        $userInfo['userpassword'] = isset($info[0]["userpassword"][0]) ? $info[0]["userpassword"][0] : '';

        return $userInfo;
    }

    public function findGroup($findStr) {
        $filter = "(&(objectClass=groupOfUniqueNames)(cn=$findStr))";
        $result = ldap_search($this->connect, $this->base_cn, $filter);
        $info = ldap_get_entries($this->connect, $result);
        $groupInfo['cn'] = isset($info[0]["cn"][0]) ? $info[0]["cn"][0] : '';
        $groupInfo['description'] = isset($info[0]["description"][0]) ? $info[0]["description"][0] : '';
        $groupInfo['gidnumber'] = isset($info[0]["gidnumber"][0]) ? $info[0]["gidnumber"][0] : '';
        $groupInfo['objectclass'] = isset($info[0]["objectclass"][0]) ? $info[0]["objectclass"][0] : '';
        $groupInfo['count'] = isset($info["count"]) ? $info["count"] : 0;
        if (isset($info[0]["uniquemember"])) {
            foreach ($info[0]["uniquemember"] as &$member) {
                $memberArr = explode(',', $member);
                $member = str_replace('uid=', '', $memberArr[0]);
            }
        }
        $groupInfo['memberuid'] = isset($info[0]["uniquemember"]) ? $info[0]["uniquemember"] : '';

        return $groupInfo;
    }

    function addToGroup($uid, $cn) {
        $dn = 'cn=' . $cn . ',ou=' . $this->group_ou . ',' . $this->base_cn;
        $udn = 'uid=' . $uid . ',ou=' . $this->person_ou . ',' . $this->base_cn;
        $info["uniquemember"][0] = $udn;
        return @ldap_mod_add($this->connect, $dn, $info);
    }

    function delToGroup($uid, $cn) {
        $dn = 'cn=' . $cn . ',ou=' . $this->group_ou . ',' . $this->base_cn;
        $udn = 'uid=' . $uid . ',ou=' . $this->person_ou . ',' . $this->base_cn;
        $info["uniquemember"][0] = $udn;
        return @ldap_mod_del($this->connect, $dn, $info);
    }

    /**
     * 添加群组
     * @param type $groupArr
     * @return type
     */
    public function addGroup($groupArr) {
        $dn = 'cn=' . $groupArr['cn'] . ',ou=' . $this->group_ou . ',' . $this->base_cn;

        $res = ldap_add($this->connect, $dn, $groupArr);

        return $res;
    }

    public function editGroup($groupArr,$newName) {
        $dn = 'cn=' . $groupArr['cn'] . ',ou=' . $this->group_ou . ',' . $this->base_cn;
        $res = ldap_modify($this->connect, $dn, $groupArr);
	if($newName!=$groupArr['cn']){
		$newParent = 'ou=' . $this->group_ou . ',' . $this->base_cn;
		$newRdn = 'cn='.$newName;
		$rt = ldap_rename($this->connect,$dn,'cn='.$newName,$newParent,true);
	}
        return $res;
    }

    public function deleteGroup($cn) {
        $dn = 'cn=' . $cn . ',ou=' . $this->group_ou . ',' . $this->base_cn;
        $res = ldap_delete($this->connect, $dn);
        return $res;
    }

    public function deleteUser($uid) {
        $dn = 'uid=' . $uid . ',ou=' . $this->person_ou . ',' . $this->base_cn;
        $res = ldap_delete($this->connect, $dn);
        return $res;
    }

    public function addUser($userArr) {
        $dn = 'uid=' . $userArr['uid'][0] . ',ou=' . $this->person_ou . ',' . $this->base_cn;

        $largestUID = $this->findLargestUidNumber();
        if ($largestUID > 0) {
            $largestUID++;
        } else {
            $largestUID = 1;
        }
        $userArr['uidnumber'][0] = $largestUID;

        $res = ldap_add($this->connect, $dn, $userArr);
        return $res;
    }

    public function editUser($userArr) {
        $dn = 'uid=' . $userArr['uid'][0] . ',ou=' . $this->person_ou . ',' . $this->base_cn;
        $res = ldap_modify($this->connect, $dn, $userArr);
        return $res;
    }

    public function renameUserToOld($uid) {
        $dn = 'uid=' . $uid . ',ou=' . $this->person_ou . ',' . $this->base_cn;
        $newRdn = 'uid=' . $uid;
        $newParent = 'ou=' . $this->old_person_ou . ',' . $this->base_cn;
        $res = ldap_rename($this->connect, $dn, $newRdn, $newParent, true);
        return $res;
    }
    
    public function renameUserToOrigin($uid) {
        $dn = 'uid=' . $uid . ',ou=' . $this->old_person_ou . ',' . $this->base_cn;
        $newRdn = 'uid=' . $uid;
        $newParent = 'ou=' . $this->person_ou . ',' . $this->base_cn;
        $res = ldap_rename($this->connect, $dn, $newRdn, $newParent, true);
        return $res;
    }

    public function userCheck($user, $pass) {
        $user = 'uid=' . $user . ',' . $this->base_cn;

        ldap_set_option($this->connect, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($this->connect, LDAP_OPT_REFERRALS, 0);

        return ldap_bind($this->connect, $user, $pass);
    }

    public function userList() {
        $userList = array();

        $filter = "objectClass=posixAccount";

        //获取所有用户
        $search = ldap_search($this->connect, 'ou=' . $this->person_ou . ',' . $this->base_cn, $filter, $this->justthese) or die("服务器忙，请稍候再试！");
        $info = ldap_get_entries($this->connect, $search);
        
        //获取当前的群组信息
        $groupList = $this->groupList();

        for ($i = 0; $i < $info["count"]; $i++) {
            $userList[$i]['id'] = $i + 1;
            $userList[$i]['cn'] = isset($info[$i]["cn"][0]) ? $info[$i]["cn"][0] : '';
            $userList[$i]['sn'] = isset($info[$i]["sn"][0]) ? $info[$i]["sn"][0] : '';
            $userList[$i]['displayname'] = isset($info[$i]["displayname"][0]) ? $info[$i]["displayname"][0] : '';
            $userList[$i]['uid'] = isset($info[$i]["uid"][0]) ? $info[$i]["uid"][0] : '';
            $userList[$i]['mail'] = isset($info[$i]["mail"][0]) ? $info[$i]["mail"][0] : '';
            $userList[$i]['mobile'] = isset($info[$i]["mobile"][0]) ? $info[$i]["mobile"][0] : '';
            $userList[$i]['telephonenumber'] = isset($info[$i]["telephonenumber"][0]) ? $info[$i]["telephonenumber"][0] : '';
            $userList[$i]['employeetype'] = isset($info[$i]["employeetype"][0]) ? $info[$i]["employeetype"][0] : '';
            $userList[$i]['userpassword'] = isset($info[$i]["userpassword"][0]) ? $info[$i]["userpassword"][0] : '';
            $userList[$i]['group'] = '';
            if ($groupList != '') {
                foreach ($groupList as $groupDetail) {
                    if ($groupDetail != '' && $groupDetail['memberuid'] != '') {
                        foreach ($groupDetail['memberuid'] as $uid) {
                            $uidArr = explode(',', $uid);
                            $uid = str_replace('uid=', '', $uidArr[0]);
                            if ($uid == $userList[$i]['uid']) {
                                $userList[$i]['group'] .= $groupDetail['cn'] . '、';
                            }
                        }
                    }
                }
            }
            $userList[$i]['group'] = trim($userList[$i]['group'], '、');
        }

        return $userList;
    }
    public function oldUserList() {
        $userList = array();

        $filter = "objectClass=posixAccount";

        //获取所有用户
        $search = ldap_search($this->connect, 'ou=' . $this->old_person_ou . ',' . $this->base_cn, $filter, $this->justthese) or die("服务器忙，请稍候再试！");
        $info = ldap_get_entries($this->connect, $search);
        
        //获取当前的群组信息
        $groupList = $this->groupList();

        for ($i = 0; $i < $info["count"]; $i++) {
            $userList[$i]['id'] = $i + 1;
            $userList[$i]['cn'] = isset($info[$i]["cn"][0]) ? $info[$i]["cn"][0] : '';
            $userList[$i]['sn'] = isset($info[$i]["sn"][0]) ? $info[$i]["sn"][0] : '';
            $userList[$i]['displayname'] = isset($info[$i]["displayname"][0]) ? $info[$i]["displayname"][0] : '';
            $userList[$i]['uid'] = isset($info[$i]["uid"][0]) ? $info[$i]["uid"][0] : '';
            $userList[$i]['mail'] = isset($info[$i]["mail"][0]) ? $info[$i]["mail"][0] : '';
            $userList[$i]['mobile'] = isset($info[$i]["mobile"][0]) ? $info[$i]["mobile"][0] : '';
            $userList[$i]['telephonenumber'] = isset($info[$i]["telephonenumber"][0]) ? $info[$i]["telephonenumber"][0] : '';
            $userList[$i]['employeetype'] = isset($info[$i]["employeetype"][0]) ? $info[$i]["employeetype"][0] : '';
            $userList[$i]['userpassword'] = isset($info[$i]["userpassword"][0]) ? $info[$i]["userpassword"][0] : '';
            $userList[$i]['group'] = '';
            if ($groupList != '') {
                foreach ($groupList as $groupDetail) {
                    if ($groupDetail != '' && $groupDetail['memberuid'] != '') {
                        foreach ($groupDetail['memberuid'] as $uid) {
                            $uidArr = explode(',', $uid);
                            $uid = str_replace('uid=', '', $uidArr[0]);
                            if ($uid == $userList[$i]['uid']) {
                                $userList[$i]['group'] .= $groupDetail['cn'] . '、';
                            }
                        }
                    }
                }
            }
            $userList[$i]['group'] = trim($userList[$i]['group'], '、');
        }

        return $userList;
    }

    public function groupList() {
        $groupList = array();

        $filter = "objectClass=groupOfUniqueNames";
        $search = ldap_search($this->connect, $this->base_cn, $filter) or die("服务器忙，请稍候再试！");
        $info = ldap_get_entries($this->connect, $search);

        for ($i = 0; $i < $info["count"]; $i++) {
            $groupList[$i]['id'] = $i + 1;
            $groupList[$i]['cn'] = isset($info[$i]["cn"][0]) ? $info[$i]["cn"][0] : '';
            $groupList[$i]['description'] = isset($info[$i]["description"][0]) ? $info[$i]["description"][0] : '';
            $groupList[$i]['count'] = isset($info[$i]["count"]) ? $info[$i]["count"] : '';
            $groupList[$i]['dn'] = isset($info[$i]["dn"]) ? $info[$i]["dn"] : '';
            if (isset($info[$i]["uniquemember"])) {
                foreach ($info[$i]["uniquemember"] as &$member) {
                    $memberArr = explode(',', $member);
                    $member = str_replace('uid=', '', $memberArr[0]);
                }
            }
            $groupList[$i]['memberuid'] = isset($info[$i]["uniquemember"]) ? $info[$i]["uniquemember"] : '';
        }
        return $groupList;
    }

    function findLargestUidNumber() {
        $base = "ou=" . $this->person_ou . "," . $this->base_cn;
        $s = ldap_search($this->connect, $base, 'uidnumber=*');

        if ($s) {
            $result = ldap_get_entries($this->connect, $s);
            $count = $result['count'];
            $biguid = 1;
            if ($count > 0) {
                $biguid = $result[$count - 1]['uidnumber'][0];
            }
            return $biguid;
        }
        return null;
    }

    function findLargestGidNumber() {
        $s = ldap_search($this->connect, "ou=" . $this->group_ou . "," . $this->base_cn, 'gidnumber=*');
        if ($s) {
            $result = ldap_get_entries($this->connect, $s);
            $biggid = 1;
            $count = $result['count'];
            if ($count > 0) {
                $biggid = $result[$count - 1]['gidnumber'][0];
            }
            return $biggid;
        }
        return null;
    }

}
